package se.sudoku;

import se.sudoku.SudokuGame;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.os.Handler;
import android.os.Message;
import android.util.Log;


public class Client implements Runnable {
	public static String SERVERIP; // = "127.0.0.1";
	public int SERVERPORT = 2500;
	public DatagramSocket clientSocket;
	private SudokuGame game;
	char changed = '-';
	String receivedPuzzle;
	public boolean hasQuit;
	public Client(SudokuGame p){
		game = p;
	}
	
	
	

	public void run() {
		try {
			hasQuit=false;
			/*// Retrieve the ServerName
			SERVERIP = game.IP;
			InetAddress serverAddr = InetAddress.getByName(SERVERIP);

			Log.d("UDP", "C: Connecting...'" + SERVERIP);
			 Create new UDP-Socket 
			clientSocket = new DatagramSocket();
			*/
			
			SERVERIP = game.IP;			
			InetAddress serverAddr = InetAddress.getByName(SERVERIP);
			Log.d("UDP", "C: Connecting... to:" + SERVERIP);
			/* Create new UDP-Socket */
			clientSocket = new DatagramSocket();
			clientSocket.setSoTimeout(30000);
			
			byte[] initbuf= new byte[1];
			initbuf="1".getBytes();
			DatagramPacket initpacket = new DatagramPacket(initbuf, initbuf.length,serverAddr,SERVERPORT);
			clientSocket.send(initpacket);
			Log.d("UDP", "C: Sent hello...");
			
			/*
			 * GET STARTING BOARD AND SOLUTION
			 */
			
			byte[] puzzleByte = new byte[81];
			DatagramPacket puzzlePacket = new DatagramPacket(puzzleByte, puzzleByte.length);
			clientSocket.receive(puzzlePacket);
			Log.d("UDP", "C: Received...puzzle: '" + new String(puzzlePacket.getData()) + "'");
			game.setStartingBoard(new String(puzzlePacket.getData()));

			puzzlePacket = new DatagramPacket(puzzleByte, puzzleByte.length);
			clientSocket.receive(puzzlePacket);
			Log.d("UDP", "C: Received...facit: '" + new String(puzzlePacket.getData()) + "'");
			game.setFacit(new String(puzzlePacket.getData()));
			
			int myProgInt;
			String playerData;
			boolean isFinished=false;
			byte[] buf = new byte[85];
			DatagramPacket packet;
			String receivedData;
			int playerProgress;
			int opponentProgress;
		
			while(!hasQuit){
				
				myProgInt = game.getProgress();
				
				if(game.getNumUsedTiles()==81){
					playerData="0";
					if(game.isCorrectBoard()){
						playerData="1";
						hRefresh.sendEmptyMessage(3);
						isFinished=true;
					}
				}
				else {
					playerData="0";
				}
				
					
				
				if(myProgInt<10)
					playerData += "0"+myProgInt;
				else
					playerData += ""+myProgInt;
				
				if(game.getBoardChanged()) {
					
					playerData += "+";
					game.setBoardChanged(false);
				}
				else
				{
					playerData += "-";
				}
				
				playerData += game.getBoard();	
				
				
				synchronized (this) {
					  this.wait(100);
				}
							
				buf = playerData.getBytes();
				packet = new DatagramPacket(buf, buf.length,
						serverAddr, SERVERPORT);
				//Log.d("UDP", "C: Sending packet...");
				Log.d("UDP", "C: Sending packet ... '" + new String(packet.getData())
				+ "'");
				
				clientSocket.send(packet);
				Log.d("UDP", "C: Done.");
				
				
				if(!hasQuit)
				{				
				
					clientSocket.receive(packet);
					receivedData = new String(packet.getData());
					
					if(Integer.parseInt(""+receivedData.charAt(0))==1)  //Opponent has finished
					{
						hRefresh.sendEmptyMessage(3);
						isFinished = true;
					}
					
					
					playerProgress = Integer.parseInt(""+playerData.substring(1, 3));
					opponentProgress = Integer.parseInt(""+receivedData.substring(1, 3));
	
					game.setOpponentProgBarValue(opponentProgress);
					hRefresh.sendEmptyMessage(1);
					Log.v("PROGRESS, self: " + playerProgress + ", opponent: " + opponentProgress, "asd");
					
					
					game.calcProgress();
					game.setPlayerProgBarValue();
					
					changed = receivedData.charAt(3);
					
					if(changed == '+') {
						
						receivedPuzzle = receivedData.substring(4);
						game.setBoard(receivedPuzzle);
					
					}
												
				}
				
			
			
				if(isFinished) {
					Log.v("UDP", "server isFinished = true and quit");
					break;
				}
				
				
				
				/*
				 * Create UDP-packet with data & destination(url+port)
				 */
				
				/*
				String s = game.getBoard();
				byte[] buf = s.getBytes();
				DatagramPacket packet = new DatagramPacket(buf, buf.length,
						serverAddr, SERVERPORT);
				Log.d("UDP", "C: Sending: '" + new String(buf) + "'");

				
				synchronized (this) {
					  this.wait(500);
					}
				clientSocket.send(packet);
				Log.d("UDP", "C: Sent.");
				Log.d("UDP", "C: Recieving packet...");
				//clientSocket.receive(packet);
				//String recivedPuzzle = new String(packet.getData());
				//game.setBoard(recivedPuzzle);
				Log.d("UDP", "C: Received: '" + new String(packet.getData())
						+ "'");
				Log.d("UDP", "C: Done.");
				*/
				
			}
			clientSocket.close();
			
		} catch (Exception e) {
			Log.e("UDP", "C: Error", e);
			hRefresh.sendEmptyMessage(2);	
		}
	}

Handler hRefresh = new Handler(){
    @Override
    public void handleMessage(Message msg) {
    switch(msg.what){
         case 1:
             /*Refresh UI*/
             game.redrawBoard();
             break;
         case 2:
        	 game.toggleTimeOut();
             break;
         case 3:
 			game.setScoreBoard(0);
 			break;        
       }
    }
};
	
}